// Copyright 2012 Google Inc. All Rights Reserved.

package com.google.superlists.servlet;

import com.google.api.client.googleapis.GoogleHeaders;
import com.google.api.client.googleapis.batch.json.JsonBatchCallback;
import com.google.api.client.googleapis.json.GoogleJsonError;
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;

/**
 * A callback that sets a future on success, and throws an exception on failure.
 * 
 * @author sven@google.com (Sven Mawson)
 */
public class FutureCallback<T> extends JsonBatchCallback<T> {

  public static <X> FutureCallback<X> create(BaseAction action, String... names) {
    return new FutureCallback<X>(action, SettableFuture.<X>create(), names);
  }

  private final BaseAction action;
  private final SettableFuture<T> future;
  private final ImmutableList<String> names;

  private FutureCallback(BaseAction action, SettableFuture<T> future, String... names) {
    this.action = action;
    this.future = future;
    this.names = ImmutableList.copyOf(names);
  }

  /**
   * Returns the future this callback is associated with.
   */
  public ListenableFuture<T> getFuture() {
    return future;
  }

  @Override
  public void onSuccess(T result, GoogleHeaders responseHeaders) {
    future.set(result);
    action.addContentLength("response.size", responseHeaders);
    for (String name : names) {
      action.addContentLength(name, responseHeaders);
    }
  }

  @Override
  public void onFailure(GoogleJsonError e, GoogleHeaders responseHeaders) {
    throw new RuntimeException(e.toPrettyString());
  }
}
